package tt.com.depositmessage.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import tt.com.common.enums.Status;
import tt.com.common.model.Dead;
import tt.com.common.model.TombDeposit;
import tt.com.common.model.TombLand;
import tt.com.common.util.CommonResult;
import tt.com.common.util.PageUtil;
import tt.com.depositmessage.mapper.DepositMapper;
import tt.com.depositmessage.service.DepositService;
import tt.com.depositmessage.vo.DeadMessageVo;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class DepositServiceImpl extends ServiceImpl<DepositMapper,TombDeposit> implements DepositService {

    @Autowired
    private DepositMapper depositMapper;

    /**
     * 展示寄存业务信息
     * @param i 0为展示味寄存信息，1为展示以寄存信息（默认为0，展示未寄存信息）
     * @param pageUtil
     * @return
     */
    @Override
    public CommonResult showDepositMessage(int i, PageUtil pageUtil) {
        List<TombDeposit> list = baseMapper.selectList(null);
        pageUtil.setTotalSize(list.size());
        IPage<TombDeposit> page = new Page<>(pageUtil.getPageIndex(),pageUtil.getPageSize());
        QueryWrapper<TombDeposit> qw = new QueryWrapper();
        qw.ne("data_status",0);
        if (i == 0){
            qw.ne("deposit_status",1);
            IPage<TombDeposit> list1 = baseMapper.selectPage(page,qw);
            pageUtil.setData(list1);
            return CommonResult.buildR(Status.OK,"返回所有未寄存信息",pageUtil);
        }else {
            qw.eq("deposit_status",1);
            IPage<TombDeposit> list1 = baseMapper.selectPage(page,qw);
            pageUtil.setData(list1);
            return CommonResult.buildR(Status.OK,"返回所有除未寄存外信息",pageUtil);
        }
    }

    /**
     * 修改信息
     * @param tombDeposit
     * @return
     */
    @Override
    public CommonResult changeDepositMessage(TombDeposit tombDeposit) {
        if (baseMapper.updateById(tombDeposit)==1){
            return CommonResult.buildR(Status.OK,"数据修改成功");
        }else {
            return CommonResult.buildR(Status.DEFAULT,"数据修改失败");
        }
    }

    /**
     * 刷新
     * @return
     */
    @Override
    public CommonResult RefreshDepositMessage(PageUtil pageUtil) {
        List<TombDeposit> list = baseMapper.selectList(null);
        if (list.size()<=0){
            return CommonResult.buildR(Status.OK,"数据为空",pageUtil);
        }
        pageUtil.setTotalSize(list.size());
        IPage<TombDeposit> page = new Page<>(pageUtil.getPageIndex(),pageUtil.getPageSize());
        QueryWrapper<TombDeposit> qw = new QueryWrapper();
        qw.ne("data_status",0);
        IPage<TombDeposit> list1 = baseMapper.selectPage(page,qw);
        pageUtil.setData(list1);
        return CommonResult.buildR(Status.OK,"已返回所有数据",pageUtil);
    }

    /**
     * 查询信息
     * @param tombDeposit
     * @return
     */
    @Override
    public CommonResult selDepositMessage(PageUtil pageUtil ,TombDeposit tombDeposit) {
        List<TombDeposit> list = baseMapper.selectList(null);
        pageUtil.setTotalSize(list.size());
        List<TombDeposit> list1 = depositMapper.selDepositMessage(pageUtil,tombDeposit);
        pageUtil.setData(list1);
        return CommonResult.buildR(Status.OK,"返回查询结果",pageUtil);
    }

    /**
     * 伪删除信息
     * @param tombDeposit
     * @return
     */
    @Override
    public CommonResult delDepositMessage(TombDeposit tombDeposit) {
        tombDeposit.setDataStatus(0);
        if (baseMapper.updateById(tombDeposit)==1){
            return CommonResult.buildR(Status.OK,"删除成功");
        }else {
            return CommonResult.buildR(Status.OK,"删除失败");
        }
    }

    /**
     * 添加信息
     * @param tombDeposit
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult insertDepositMessage(int depositYear ,TombDeposit tombDeposit) {
        //数据库没有自增  查询所有数据  插入新数据的id为所有数据+1
        List<TombDeposit> list1 = baseMapper.selectList(null);
        tombDeposit.setId((list1.size()+1)+"");
        //设置寄存证编号
        String id = tombDeposit.getAllDeadId();
        tombDeposit.setDepositNo("Deposit-"+id);
        tombDeposit.setCreateTime(new Date());
        tombDeposit.setLastUpdateTime(new Date());
        tombDeposit.setDataStatus(1);
        //根据寄存开始时间和寄存时间计算寄存结束时间
        if (tombDeposit.getDepositStart()!=null){
            Calendar instance = Calendar.getInstance();
            instance.setTime(tombDeposit.getDepositStart());
            int year = instance.get(Calendar.YEAR);
            instance.set(Calendar.YEAR,year+depositYear);
            Date time = instance.getTime();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            dateFormat.format(time);
            tombDeposit.setDepositEnd(time);
        }
        //查找墓地信息，根据信息拼接地址  例:XXXX墓园X排X列
        List<TombLand> list = depositMapper.selTombLandMessage(tombDeposit.getTombId());
        for (TombLand item:list){
            tombDeposit.setDepositLocation(item.getName()+item.getRow()+"排"+item.getColumn()+"列");
        }

        //获取墓地信息 判断墓地是单穴还是双穴
        List<TombLand> lands = depositMapper.selTombLandMessage(tombDeposit.getTombId());
        TombLand tombLand = null;
        for (TombLand item:lands){
            tombLand = item;
        }
        //墓地为单穴
        if (tombLand.getGraveNumType()==1){
            if (baseMapper.insert(tombDeposit)==1){
                //status为状态码
                if (depositMapper.updateTombLand(tombDeposit.getTombId(),0)==1){
                    return CommonResult.buildR(Status.OK,"数据添加成功");
                }else {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return CommonResult.buildR(Status.DEFAULT,"回滚事务");
                }
            }else {
                return CommonResult.buildR(Status.DEFAULT,"数据添加失败");
            }
        }
        //墓地为双穴
        if (baseMapper.insert(tombDeposit)==1){
            //status为状态码
            if (depositMapper.updateTombLand(tombDeposit.getTombId(),1)==1){
                return CommonResult.buildR(Status.OK,"数据添加成功");
            }else {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return CommonResult.buildR(Status.DEFAULT,"回滚事务");
            }
        }else {
            return CommonResult.buildR(Status.DEFAULT,"数据添加失败");
        }

    }

    /**
     * 合葬
     * @param id 合葬逝者id
     * @param tombDeposit
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult updateAddDeposit(String id,TombDeposit tombDeposit) {
        //优化  重复输入
        TombDeposit t = baseMapper.selectById(tombDeposit.getId());
        //获取逝者id 判断是单人还是双人
        String allDeadId = t.getAllDeadId();
        String[] split = allDeadId.split(",");
        if (split.length>1){
            return CommonResult.buildR(Status.DEFAULT,"墓地已满");
        }

        t.setAllDeadId(t.getAllDeadId()+","+id);
        if (baseMapper.updateById(t)==1){
            if (depositMapper.updateTombLand(t.getTombId(),0)==1){
                return CommonResult.buildR(Status.OK,"合葬信息录入成功");
            }else {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return CommonResult.buildR(Status.DEFAULT,"回滚事务");
            }
        }else {
            return CommonResult.buildR(Status.DEFAULT,"合葬信息录入失败");
        }
    }

    /**
     * 返回所有空格位
     * @return
     */
    @Override
    public CommonResult showTombLand() {
        List<TombLand> list = depositMapper.showTombLand();
        return CommonResult.buildR(Status.OK,"返回所有空格位",list);
    }

    /**
     * 增加寄存时间，续费寄存服务，打印收款收据
     * @param depositYear 寄存所需年份
     * @param tombDeposit
     * @return
     */
    @Override
    public CommonResult renewDeposit(HttpServletResponse response, int depositYear, TombDeposit tombDeposit) {
        TombDeposit t = baseMapper.selectById(tombDeposit.getId());
        //打印殡仪馆收款收据
        // 模板路径
        URL path = this.getClass().getResource("/printTemplate/jifang.pdf");
        // 生成文件路径
        String filename = "收据-"+t.getDepositNo()+".pdf";
        //根据模板填入信息
        Map<String, Object> datas = new HashMap<>();
        datas.put("dead_no", t.getDepositNo());
        datas.put("end_time1", t.getDepositEnd());

        if (t.getDepositStart()!=null){
            //创建日历类
            Calendar instance = Calendar.getInstance();
            //获取寄存结束时间
            instance.setTime(t.getDepositEnd());
            //提取寄存结束时间的年份
            int year = instance.get(Calendar.YEAR);
            //续费 增加寄存时间
            instance.set(Calendar.YEAR,year+depositYear);
            Date time = instance.getTime();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            dateFormat.format(time);
            t.setDepositEnd(time);
            datas.put("end_time2", time);
        }
        if (baseMapper.updateById(t)!=1){
            return CommonResult.buildR(Status.DEFAULT,"续费失败");
        }
        CommonResult result = printPdf(response,path,filename,datas);
        return result;
    }

    /**
     * 迁出骨灰盒
     * @param address 迁出地址
     * @param tombDeposit
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult moveBone(String address, TombDeposit tombDeposit) {

        TombDeposit t = baseMapper.selectById(tombDeposit.getId());

        t.setDepositStatus(2);
        t.setBoneAshGone(address);
        t.setQuitTime(new Date());
        t.setLastUpdateTime(new Date());
        t.setDepositLocation("");

        String allDeadId = t.getAllDeadId();
        String[] split = allDeadId.split(",");

        //修改寄存表信息
        //修改成功：修改逝者信息 修改失败：回滚事务
        //逝者信息修改成功：修改墓地信息 修改失败：回滚事务
        if (depositMapper.updateMoveBoneStatus(t.getTombId())==1){
            t.setTombId("");
            if (baseMapper.updateById(t)==1){
                for (int i = 0;i<split.length;i++){
                    if (depositMapper.updateDeadBonb(split[i],address)!=1){
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                        return CommonResult.buildR(Status.OK,"回滚");
                    }
                }
                return CommonResult.buildR(Status.OK,"迁出信息修改成功");
            }else {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return CommonResult.buildR(Status.OK,"回滚");
            }
        }else {
            return CommonResult.buildR(Status.DEFAULT,"迁出信息修改失败");
        }

    }

    /**
     * 打印寄存证
     * @param tombDeposit
     * @return
     */
    @Override
    public CommonResult createDepositCard(HttpServletResponse response, TombDeposit tombDeposit) {
        TombDeposit tombDeposit1 = baseMapper.selectById(tombDeposit.getId());
        // 模板路径
        URL path = this.getClass().getResource("/printTemplate/jifang.pdf");
        // 生成文件路径
        String filename = "寄存卡-"+tombDeposit1.getDepositNo()+".pdf";
        //根据模板填入信息
        Map<String, Object> datas = new HashMap<>();
        datas.put("deposit_no", tombDeposit1.getDepositNo());
        datas.put("deposit_location", tombDeposit1.getDepositLocation());
        datas.put("deposit_start", tombDeposit1.getDepositStart());
        datas.put("deposit_end", tombDeposit1.getDepositEnd());
        datas.put("relation_phone", tombDeposit1.getRelationPhone());
        //调用打印PDF的方法
        CommonResult result = printPdf(response,path,filename,datas);
        return result;
    }

    /**
     * 打印安放证
     * @param tombDeposit
     * @return
     */
    @Override
    public CommonResult createPutCertificates(HttpServletResponse response, TombDeposit tombDeposit) {
        //三表联查有问题
        //寄存表逝者id 有1，2的情况
        //匹配不上逝者表id
        List<DeadMessageVo> list = depositMapper.selDeadMessageVo(tombDeposit);
        DeadMessageVo vo = null;
        for (DeadMessageVo item:list){
            vo = item;
        }
        String grave_num_type = null;
        String species = null;
        if (vo.getGraveNumType() == 1){
            grave_num_type = "单穴";
        }else {
            grave_num_type = "双穴";
        }
        if (vo.getSpecies() == 0){
            species = "墓地";
        }else if (vo.getSpecies() == 1){
            species = "骨灰楼";
        }else if (vo.getSpecies() == 2){
            species = "壁穴";
        }else if (vo.getSpecies() == 3){
            species = "草坪";
        }else {
            species = "树葬";
        }
        // 模板路径
        URL path = this.getClass().getResource("/printTemplate/anfang.pdf");
        System.out.println(path);
        // 生成文件路径
        String filename = "安放证-"+vo.getDeadNo()+".pdf";
        //根据模板填入信息
        Map<String, Object> datas = new HashMap<>();
        datas.put("dead_no", vo.getDeadNo());
        datas.put("name", vo.getName());
        datas.put("deposit_location", vo.getDepositLocation());
        datas.put("relation_phone", vo.getRelationPhone());
        datas.put("acreage", vo.getAcreage());
        datas.put("grave_num_type", grave_num_type);
        datas.put("species", species);
        datas.put("height", vo.getHeight());
        //调用打印PDF的方法
        CommonResult result = printPdf(response,path,filename,datas);
        return result;
    }

    /**
     * 打印骨灰迁出证明
     * @param tombDeposit
     * @return
     */
    @Override
    public CommonResult createBonbMoveOut(HttpServletResponse response, TombDeposit tombDeposit) {
        List<DeadMessageVo> list = depositMapper.selDeadMessageVo(tombDeposit);
        DeadMessageVo vo = null;
        for (DeadMessageVo item:list){
            vo = item;
        }
        // 模板路径
        URL path = this.getClass().getResource("/printTemplate/qianchu.pdf");
        System.out.println(path);
        // 生成文件路径
        String filename = "骨灰迁出证明-"+vo.getDeadNo()+".pdf";
        //根据模板填入信息
        Map<String, Object> datas = new HashMap<>();
        datas.put("dead_no", vo.getDeadNo());
        datas.put("name", vo.getName());
        datas.put("deposit_location", vo.getDepositLocation());
        datas.put("relation_name", vo.getRelationName());
        //调用打印PDF的方法
        CommonResult result = printPdf(response,path,filename,datas);
        return result;
    }

    /**
     * 打印PDF
     * @param response
     * @param path 模板文件路径
     * @param filename 文件保存路径
     * @param datas 填入PDF表单中的数据
     * @return
     */
    public CommonResult printPdf(HttpServletResponse response,URL path,String filename,Map<String, Object> datas){
        PdfReader reader;
        OutputStream os = null;
        ByteArrayOutputStream baos = null;
        PdfStamper stamper;

        try {
            os = response.getOutputStream();
            // 读入pdf表单
            reader = new PdfReader(path);
            baos = new ByteArrayOutputStream();
            // 根据表单生成一个新的pdf
            stamper = new PdfStamper(reader, baos);
            // 获取pdf表单
            AcroFields formTexts = stamper.getAcroFields();

            // 设置字体(这里设置为系统字体，你也可以引入其他的字体)，不设置很可能，中文无法显示。
            BaseFont bf = BaseFont.createFont("C:/WINDOWS/Fonts/SIMSUN.TTC,1",
                    BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
            formTexts.addSubstitutionFont(bf);

            // 数据查询后，值的植入 强烈推荐键值方式，其他方式很容易混
            Set<String> keySet =  datas.keySet();
            for (String key : keySet) {
                formTexts.setField(key, datas.get(key).toString());
            }

            stamper.setFormFlattening(true); // 这个必须设
            stamper.close();

            // 创建一个pdf实例
            Document document = new Document();
            PdfCopy copy = new PdfCopy(document, os);
            document.open();
            PdfImportedPage importedPage = copy.getImportedPage(new PdfReader(baos.toByteArray()), 1);
            copy.addPage(importedPage);
            document.close(); // open和close一套

            // 强制下载
            //response.reset();
            response.setContentType("application/pdf");
            response.setHeader("Content-Disposition", "attachment;fileName="
                    + URLEncoder.encode(filename, "UTF-8"));

        } catch (IOException | DocumentException e) {
            e.printStackTrace();
        } finally { // 最后一定要关闭流
            try {
                baos.close();
                os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return CommonResult.buildR(Status.OK,"打印成功");
    }

    /**
     * 变更格位
     * @param tombDeposit
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult changeTombLand(TombDeposit tombDeposit) {
        TombDeposit t = baseMapper.selectById(tombDeposit.getId());

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
        //获取寄存到期时间
        Date time1 = t.getDepositEnd();
        Date time2 = new Date();

        String endDate = sdf.format(time1);
        String nowDate = sdf.format(time2);

        try {
            time1 = sdf.parse(endDate);
            time2 = sdf.parse(nowDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        Long timeEnd = time1.getTime();
        Long timeNow = time2.getTime();
        //计算寄存结束时间和现在的时间差是否有一年
        int day = (int) ((timeEnd - timeNow) / (24*3600*1000));
        if (day<=0){
            return CommonResult.buildR(Status.OK,"寄存到期"+day+"天，请及时续费");
        }else if (day>=0 && day<=365){
            return CommonResult.buildR(Status.OK,"管理费到期时间一年以内的无法变更，请先续费");
        }
        System.out.println(day);
        String old_tom_id = t.getTombId();
        String new_tom_id = tombDeposit.getTombId();

        if (depositMapper.updateMoveBoneStatus(old_tom_id)==1 & depositMapper.updateTomeLand1(new_tom_id)==1){
            //设置变更后的格子id
            t.setTombId(new_tom_id);
            //设置变更后的寄存位置
            List<TombLand> list = depositMapper.selTombLandMessage(new_tom_id);
            for (TombLand item:list){
                t.setDepositLocation(item.getName()+item.getRow()+"排"+item.getColumn()+"列");
            }
            t.setLastUpdateTime(new Date());
            if (baseMapper.updateById(t)==1){
                return CommonResult.buildR(Status.OK,"已变更格位");
            }else {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return CommonResult.buildR(Status.DEFAULT,"变更格位失败，数据已回滚");
            }
        }else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return CommonResult.buildR(Status.DEFAULT,"变更格位失败，数据已回滚");
        }
    }


}
